package com.hcc.repository.gen;

import com.hcc.repository.gen.config.GlobalConfig;
import com.hcc.repository.gen.generator.Generator;
import com.hcc.repository.gen.generator.GeneratorFactory;
import com.hcc.repository.gen.metadata.MetadataQuery;
import com.hcc.repository.gen.metadata.MetadataQueryFactory;
import com.hcc.repository.gen.metadata.dialect.JdbcMetadataQuery;
import com.hcc.repository.gen.model.TableMetadata;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;

import javax.sql.DataSource;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 代码生成器
 *
 * @author hushengjun
 * @date 2023/9/16
 */
@Slf4j
public class CodeGenerator {

    private GlobalConfig globalConfig;
    private DataSource dataSource;

    public CodeGenerator(DataSource dataSource, GlobalConfig globalConfig) {
        this.dataSource = dataSource;
        this.globalConfig = globalConfig;
    }

    public static CodeGenerator of(DataSource dataSource, GlobalConfig globalConfig) {
        return new CodeGenerator(dataSource, globalConfig);
    }

    /**
     * 生成文件
     */
    public void generate() {
        List<TableMetadata> tableMetadataList = this.queryTableMetadata();
        List<Generator> generators = GeneratorFactory.allGenerator();
        for (TableMetadata tableMetadata : tableMetadataList) {
            log.debug("开始生成表：{}，源码文件，源码路径：{}", tableMetadata.getName(), globalConfig.getPackageConfig().getSrcPath());
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            generators.forEach(g -> g.generate(tableMetadata, globalConfig));
            stopWatch.stop();
            log.debug("表：{}，源码文件生成完毕，耗时：{}ms", tableMetadata.getName(), stopWatch.getTotalTimeMillis());
        }
    }

    /**
     * 查询表的元数据信息
     * @return
     */
    private List<TableMetadata> queryTableMetadata() {
        MetadataQuery metadataQuery = MetadataQueryFactory.getMetadataQuery(globalConfig.getDbType());
        if (metadataQuery == null) {
            metadataQuery = new JdbcMetadataQuery();
        }
        metadataQuery.setDataSource(dataSource);

        return metadataQuery.buildTableMetadata(globalConfig.getGenerateTables(), globalConfig);
    }

}
